﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LL.Business;
using NanoERP.Business;
using NanoERP.Model.Poco;
using NanoERP.Model.SystemMgmt;
using Omu.ValueInjecter;


namespace NanoERP.Business.Permission
{
    /// <summary>
    /// 角色业务对象
    /// </summary>
    public class RoleService : ServiceBase
    {

        #region CRUD

        public void AddRole(SYS_Role role)
        {
            this.DbSession.Insert(role);
        }

        public void DeleteRole(Guid roleId)
        {
            var dao = this.DbSession.Delete<SYS_Role>(roleId);
        }

        public void UpdateRole(SYS_Role role)
        {
            this.DbSession.Update(role);
        }

        public void Move(Guid roleId, Guid? roleTypeId)
        {
            var dao = this.DbSession;
            var role = dao.Get<SYS_Role>(roleId);
            role.TypeId = roleTypeId;
            dao.Update(role);
        }

        public void AddRoleType(SYS_RoleType roleType)
        {
            DbSession.Insert(roleType);
        }

        public void UpdateRoleType(SYS_RoleType roleType)
        {
            DbSession.Update(roleType);
        }

        public SYS_Role GetRole(Guid id)
        {
            return DbSession.Get<SYS_Role>(id);
        }

        public void DeleteRoleType(Guid id)
        {
            DbSession.Delete<SYS_RoleType>(id);
        }

        public void MoveType(Guid typeId, Guid? desId)
        {
            var dao = this.DbSession;
            var role = dao.Get<SYS_RoleType>(typeId);
            role.ParentId = desId;
            dao.Update(role);
        }

        public SYS_RoleType GetRoleType(Guid id)
        {
            return this.DbSession.Get<SYS_RoleType>(id);
        }

        #endregion

        /// <summary>
        /// 获取用户的角色
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public RoleTree GetRoleTreeForUser(Guid userId)
        {
            var str = new StringBuilder();
            str.AppendLine("SELECT  SYS_Role.* ,");
            str.AppendLine("CONVERT(BIT,CASE WHEN dbo.SYS_Roles_Users.RoleId IS NULL ");
            str.AppendLine("THEN 0 ELSE 1 END) Checked");
            str.AppendLine("FROM dbo.SYS_User");
            str.AppendLine("CROSS JOIN dbo.SYS_Role");
            str.AppendLine("LEFT JOIN SYS_Roles_Users ON dbo.SYS_User.Id = dbo.SYS_Roles_Users.UserId");
            str.AppendLine("AND dbo.SYS_Role.Id = dbo.SYS_Roles_Users.RoleId");
            str.AppendLine("WHERE dbo.SYS_User.Id=@0 ORDER BY Sort");
            var roles = this.DbSession.SqlQuery<RoleModel>(str.ToString(), userId);
            var tree = this.GetRoleTypeTree();

            foreach (var roleModel in
                (from d in roles where d.TypeId == null select d))
            {
                tree.Roles.Add(roleModel);
            }
            Fill(tree.Children, roles);
            return tree;
        }

        /// <summary>
        /// 获取角色树
        /// </summary>
        /// <returns></returns>
        public RoleTree GetRoleTree()
        {
            var roles = this.DbSession.SqlQuery<RoleModel>("SELECT * FROM SYS_Role ORDER BY Sort");
            var tree = this.GetRoleTypeTree();

            foreach (var roleModel in
                (from d in roles where d.TypeId == null select d))
            {
                tree.Roles.Add(roleModel);
            }
            Fill(tree.Children, roles);
            return tree;
        }

        #region RoleType

        public RoleTree GetRoleTypeTree()
        {
            var list = this.GetTopRoleTypes();
            var root = new RoleTree() { Name = "角色" };
            foreach (var item in list)
            {
                var newItem = new RoleTree();
                newItem.InjectFrom(item);
                FillSubRoleTree(newItem, true);
                root.Children.Add(newItem);
            }
            return root;
        }

        public IList<SYS_RoleType> GetTopRoleTypes()
        {
            return this.DbSession.Query<SYS_RoleType>("ParentId is null Order By Sort");
        }

        private void Fill(IEnumerable<RoleTree> iList, IList<RoleModel> roles)
        {
            foreach (var model in iList)
            {
                RoleTree model1 = model;
                foreach (var role in
                    (from d in roles where d.TypeId == model1.Id select d))
                {
                    model.Roles.Add(role);
                }
                Fill(model.Children, roles);
            }
        }

        public void FillSubRoleTree(RoleTree tree, bool recursion = false)
        {
            var list = this.GetRoleTypesByParentId(tree.Id);
            foreach (var item in list)
            {
                var newItem = new RoleTree();
                newItem.InjectFrom(item);
                if (recursion)
                    FillSubRoleTree(newItem, true);
                tree.Children.Add(newItem);
            }
        }

        public IList<SYS_RoleType> GetRoleTypesByParentId(Guid roleTypeId)
        {
            return this.DbSession.Query<SYS_RoleType>("ParentId=@0 Order By Sort", roleTypeId);
        }

        public void SetRoleRights(Guid roleId, IList<Guid> rights)
        {
            var sqlHelper = this.DbSession;
            sqlHelper.ExcuteNonQuery("delete from SYS_Rights_Roles where roleId=@0", roleId);
            foreach (Guid right in rights)
            {
                sqlHelper.ExcuteNonQuery("insert into SYS_Rights_Roles(roleId,rightId) VALUES(@0,@1)", roleId, right);
            }
        }

        #endregion






    }
}
